home *** CD-ROM | disk | FTP | other *** search
/ Language/OS - Multiplatform Resource Library / LANGUAGE OS.iso / gnu / cvs-1_3.lha / cvs-1.3 / src / myndbm.c < prev    next >
C/C++ Source or Header  |  1992-03-31  |  4KB  |  213 lines

  1. /*
  2.  * Copyright (c) 1992, Brian Berliner
  3.  * 
  4.  * You may distribute under the terms of the GNU General Public License as
  5.  * specified in the README file that comes with the CVS 1.3 kit.
  6.  * 
  7.  * A simple ndbm-emulator for CVS.  It parses a text file of the format:
  8.  * 
  9.  * key    value
  10.  * 
  11.  * at dbm_open time, and loads the entire file into memory.  As such, it is
  12.  * probably only good for fairly small modules files.  Ours is about 30K in
  13.  * size, and this code works fine.
  14.  */
  15.  
  16. #include "cvs.h"
  17.  
  18. #ifdef MY_NDBM
  19.  
  20. #ifndef lint
  21. static char rcsid[] = "@(#)myndbm.c 1.5 92/03/31";
  22. #endif
  23.  
  24. static void mydbm_load_file ();
  25.  
  26. /* ARGSUSED */
  27. DBM *
  28. mydbm_open (file, flags, mode)
  29.     char *file;
  30.     int flags;
  31.     int mode;
  32. {
  33.     FILE *fp;
  34.     DBM *db;
  35.  
  36.     if ((fp = fopen (file, "r")) == NULL)
  37.     return ((DBM *) 0);
  38.  
  39.     db = (DBM *) xmalloc (sizeof (*db));
  40.     db->dbm_list = getlist ();
  41.  
  42.     mydbm_load_file (fp, db->dbm_list);
  43.     (void) fclose (fp);
  44.     return (db);
  45. }
  46.  
  47. void
  48. mydbm_close (db)
  49.     DBM *db;
  50. {
  51.     dellist (&db->dbm_list);
  52.     free ((char *) db);
  53. }
  54.  
  55. datum
  56. mydbm_fetch (db, key)
  57.     DBM *db;
  58.     datum key;
  59. {
  60.     Node *p;
  61.     char *s;
  62.     datum val;
  63.  
  64.     /* make sure it's null-terminated */
  65.     s = xmalloc (key.dsize + 1);
  66.     (void) strncpy (s, key.dptr, key.dsize);
  67.     s[key.dsize] = '\0';
  68.  
  69.     p = findnode (db->dbm_list, s);
  70.     if (p)
  71.     {
  72.     val.dptr = p->data;
  73.     val.dsize = strlen (p->data);
  74.     }
  75.     else
  76.     {
  77.     val.dptr = (char *) NULL;
  78.     val.dsize = 0;
  79.     }
  80.     free (s);
  81.     return (val);
  82. }
  83.  
  84. datum
  85. mydbm_firstkey (db)
  86.     DBM *db;
  87. {
  88.     Node *head, *p;
  89.     datum key;
  90.  
  91.     head = db->dbm_list->list;
  92.     p = head->next;
  93.     if (p != head)
  94.     {
  95.     key.dptr = p->key;
  96.     key.dsize = strlen (p->key);
  97.     }
  98.     else
  99.     {
  100.     key.dptr = (char *) NULL;
  101.     key.dsize = 0;
  102.     }
  103.     db->dbm_next = p->next;
  104.     return (key);
  105. }
  106.  
  107. datum
  108. mydbm_nextkey (db)
  109.     DBM *db;
  110. {
  111.     Node *head, *p;
  112.     datum key;
  113.  
  114.     head = db->dbm_list->list;
  115.     p = db->dbm_next;
  116.     if (p != head)
  117.     {
  118.     key.dptr = p->key;
  119.     key.dsize = strlen (p->key);
  120.     }
  121.     else
  122.     {
  123.     key.dptr = (char *) NULL;
  124.     key.dsize = 0;
  125.     }
  126.     db->dbm_next = p->next;
  127.     return (key);
  128. }
  129.  
  130. static void
  131. mydbm_load_file (fp, list)
  132.     FILE *fp;
  133.     List *list;
  134. {
  135.     char line[MAXLINELEN], value[MAXLINELEN];
  136.     char *cp, *vp;
  137.     int len, cont;
  138.  
  139.     for (cont = 0; fgets (line, sizeof (line), fp) != NULL;)
  140.     {
  141.     if ((cp = rindex (line, '\n')) != NULL)
  142.         *cp = '\0';            /* strip the newline */
  143.  
  144.     /*
  145.      * Add the line to the value, at the end if this is a continuation
  146.      * line; otherwise at the beginning, but only after any trailing
  147.      * backslash is removed.
  148.      */
  149.     vp = value;
  150.     if (cont)
  151.         vp += strlen (value);
  152.  
  153.     /*
  154.      * See if the line we read is a continuation line, and strip the
  155.      * backslash if so.
  156.      */
  157.     len = strlen (line);
  158.     if (len > 0)
  159.         cp = &line[len - 1];
  160.     else
  161.         cp = line;
  162.     if (*cp == '\\')
  163.     {
  164.         cont = 1;
  165.         *cp = '\0';
  166.     }
  167.     else
  168.     {
  169.         cont = 0;
  170.     }
  171.     (void) strcpy (vp, line);
  172.     if (value[0] == '#')
  173.         continue;            /* comment line */
  174.     vp = value;
  175.     while (*vp && isspace (*vp))
  176.         vp++;
  177.     if (*vp == '\0')
  178.         continue;            /* empty line */
  179.  
  180.     /*
  181.      * If this was not a continuation line, add the entry to the database
  182.      */
  183.     if (!cont)
  184.     {
  185.         Node *p = getnode ();
  186.         char *kp;
  187.  
  188.         kp = vp;
  189.         while (*vp && !isspace (*vp))
  190.         vp++;
  191.         *vp++ = '\0';        /* NULL terminate the key */
  192.         p->type = NDBMNODE;
  193.         p->key = xstrdup (kp);
  194.         while (*vp && isspace (*vp))
  195.         vp++;            /* skip whitespace to value */
  196.         if (*vp == '\0')
  197.         {
  198.         error (0, 0, "warning: NULL value for key `%s'", p->key);
  199.         freenode (p);
  200.         continue;
  201.         }
  202.         p->data = xstrdup (vp);
  203.         if (addnode (list, p) == -1)
  204.         {
  205.         error (0, 0, "duplicate key found for `%s'", p->key);
  206.         freenode (p);
  207.         }
  208.     }
  209.     }
  210. }
  211.  
  212. #endif                /* MY_NDBM */
  213.